//
//  BRScanView.m
//  BrezzeSaaS
//
//  Created by IOS on 2021/9/7.
//  Copyright © 2021 Brezze GWG. All rights reserved.
//

#import "BRScanView.h"

@interface BRScanView ()<AVCaptureMetadataOutputObjectsDelegate, CALayerDelegate>

@property (nonatomic,strong) UIView *centerView;

@property (nonatomic,strong) AVCaptureVideoPreviewLayer * preview;

@property (nonatomic,strong) UIView *lineView;

@end

@implementation BRScanView

- (instancetype)initWithFrame:(CGRect)frame
{
    return [self initWithFrame:frame needDown:NO];
}

- (instancetype)initWithFrame:(CGRect)frame needDown:(BOOL)isNeed
{
    self = [super initWithFrame:frame];
    if (self) {
        _isNeedDown = isNeed;
        [self setUI];
    }
    return self;
}

#pragma mark - Action --
- (void)startAnimate {
    
    self.lineView.frame = CGRectMake(5, 10, 250, 1);
    [UIView animateWithDuration:2.5 delay:0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse animations:^{
        self.lineView.frame = CGRectMake(5, 250, 250, 1);
        
    } completion:^(BOOL finished) {
        
    }];
}

- (void)stopRuning {
    [self.session stopRunning];
}

- (void)startRuning {
    dispatch_queue_t sessionQueue = dispatch_queue_create("com.youdianstar.scan", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(sessionQueue, ^{
        [self.session startRunning];
    });
    
}

// 是否打开闪光灯
- (void)openLinght:(QMUIButton *)btn {
    btn.selected = !btn.selected;
    self.isOpenLinght = btn.isSelected;
    
}

- (void)setIsOpenLinght:(BOOL)isOpenLinght {
    _isOpenLinght = isOpenLinght;
    
    if (isOpenLinght) {
        if([self.device hasTorch] && [self.device hasFlash])
        {
            if(self.device.torchMode == AVCaptureTorchModeOff)
            {
                
                if ([self.device lockForConfiguration:nil]) {
                    [self.device setTorchMode:AVCaptureTorchModeOn];
                    
                    [self.device unlockForConfiguration];
                }
                
            }
        }
    } else {
        
        if ([self.device hasTorch]) {
            [self.device lockForConfiguration:nil];
            [self.device setTorchMode:AVCaptureTorchModeOff];
            
            [self.device unlockForConfiguration];
        }
        
    }
}

#pragma mark - set UI --
- (void)setUI {
    
    
     //创建一个View
     UIView *maskView = [[UIView alloc] initWithFrame:self.bounds];
     maskView.backgroundColor = UIColorBlack;
     maskView.alpha = 0.75;
     [self addSubview:maskView];
     
    // 创建一个全屏大的path
    UIBezierPath *bpath = [UIBezierPath bezierPathWithRect:self.bounds];
    
    CGFloat bezi_w = 265.;
    CGFloat bezi_top = kScreenHeight / 2 - bezi_w / 2;
    if (self.isNeedDown) {
        bezi_top += 40;
    }
    UIBezierPath *pa = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(kScreenWidth / 2 - bezi_w / 2, bezi_top, bezi_w, bezi_w) cornerRadius:0];
    
    [bpath appendPath:pa];
    [bpath setUsesEvenOddFillRule:YES];
    
    //创建一个CAShapeLayer 图层
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = bpath.CGPath;
    shapeLayer.fillRule = kCAFillRuleEvenOdd;
    
     //添加图层蒙板
     maskView.layer.mask = shapeLayer;
     
    
    //配置扫描
    [self initQrCodeScanning];
    
    [self addSubview:self.centerView];
    [self.centerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self);
        make.top.offset(bezi_top);
        make.width.height.mas_equalTo(bezi_w);
    }];
    
    [self.centerView addSubview:self.lineView];
    
    
}

- (void)initQrCodeScanning{
    /**
     20      扫描二维码 大概的流程应该是：1.打开设备的摄像头-->2.进行二维码图像捕获-->3.获取捕获的图像进行解析-->4.取得解析结果进行后续的处理。这些流程需要用到AVFoundation这个库
     21      */
    /**
     24      上面完成了捕获的设置，但是并未正在开始'扫描'，要完成一次扫描的过程，需要用到AVCaptureSession这个类，这个session类把一次扫描看做一次会话，会话开始后才是正在的'扫描'开始,具体代码如下。
     25      */
    self.session = [[AVCaptureSession alloc] init];
//    [self.session setSessionPreset:AVCaptureSessionPresetHigh];//扫描的质量
    //获取摄像头设备
//    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;
    //创建输入流
//     AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:&error];
  //拍完照片以后，需要一个AVCaptureMetadataOutput对象将获取的'图像'输出，以便进行对其解析
//    AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc] init];

    if ([self.session canAddInput:self.input]) {
        [self.session addInput:self.input];
    }else{
         //出错处理
        NSLog(@"%@", error);
         return;
     }
    if ([self.session canAddOutput:self.output]) {
        [self.session addOutput:self.output];
     }
    //设置输出类型 有二维码 条形码等
     self.output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode  //二维码
                                    ];
     //获取输出需要设置代理，在代理方法中获取
//     [self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];

     /**
      53      接下来我们要做的不是立即开始会话(开始扫描)，如果你现在调用会话的startRunning方法的话，你会发现屏幕是一片黑，这时由于我们还没有设置相机的取景器的大小。设置取景器需要用到AVCaptureVideoPreviewLayer这个类。具体代码如下：
      54      */
     self.preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
     self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
     [self.preview setFrame:self.bounds];//设置取景器的frame
    [self.layer insertSublayer:self.preview atIndex:0];

//    CGRect size2 = CGRectMake(kScreenWidth / 2 - bezi_w / 2, kScreenHeight / 2 - bezi_w / 2, bezi_w, bezi_w);
    self.output.rectOfInterest = self.bounds;
    //开始扫码
//     [self.session startRunning];
}


// 该方法中，_preViewLayer指的是AVCaptureVideoPreviewLayer的实例对象，_session是会话对象，_metadataOutput是扫码输出流
- (void)br_coverToMetadataOutputRectOfInterestForRect:(CGRect)cropRect {
    CGSize size = self.preview.bounds.size;
    CGFloat p1 = size.height/size.width;
    CGFloat p2 = 0.0;
    AVCaptureSession *s = self.session;
    if ([s.sessionPreset isEqualToString:AVCaptureSessionPreset1920x1080]) {
        p2 = 1920./1080.;
    }
    else if ([s.sessionPreset isEqualToString:AVCaptureSessionPreset352x288]) {
        p2 = 352./288.;
    }
    else if ([s.sessionPreset isEqualToString:AVCaptureSessionPreset1280x720]) {
        p2 = 1280./720.;
    }
    else if ([s.sessionPreset isEqualToString:AVCaptureSessionPresetiFrame960x540]) {
        p2 = 960./540.;
    }
    else if ([s.sessionPreset isEqualToString:AVCaptureSessionPresetiFrame1280x720]) {
        p2 = 1280./720.;
    }
    else if ([s.sessionPreset isEqualToString:AVCaptureSessionPresetHigh]) {
        p2 = 1920./1080.;
    }
    else if ([s.sessionPreset isEqualToString:AVCaptureSessionPresetMedium]) {
        p2 = 480./360.;
    }
    else if ([s.sessionPreset isEqualToString:AVCaptureSessionPresetLow]) {
        p2 = 192./144.;
    }
    else if ([s.sessionPreset isEqualToString:AVCaptureSessionPresetPhoto]) { // 暂时未查到具体分辨率，但是可以推导出分辨率的比例为4/3
        p2 = 4./3.;
    }
    else if ([s.sessionPreset isEqualToString:AVCaptureSessionPresetInputPriority]) {
        p2 = 1920./1080.;
    }
    else if (@available(iOS 9.0, *)) {
        if ([s.sessionPreset isEqualToString:AVCaptureSessionPreset3840x2160]) {
            p2 = 3840./2160.;
        }
    }
    
    if ([self.preview.videoGravity isEqualToString:AVLayerVideoGravityResize]) {
        self.output.rectOfInterest = CGRectMake((cropRect.origin.y)/size.height,(size.width-(cropRect.size.width+cropRect.origin.x))/size.width, cropRect.size.height/size.height,cropRect.size.width/size.width);
    } else if ([self.preview.videoGravity isEqualToString:AVLayerVideoGravityResizeAspectFill]) {
        if (p1 < p2) {
            CGFloat fixHeight = size.width * p2;
            CGFloat fixPadding = (fixHeight - size.height)/2;
            self.output.rectOfInterest = CGRectMake((cropRect.origin.y + fixPadding)/fixHeight,
                                                        (size.width-(cropRect.size.width+cropRect.origin.x))/size.width,
                                                        cropRect.size.height/fixHeight,
                                                        cropRect.size.width/size.width);
        } else {
            CGFloat fixWidth = size.height * (1/p2);
            CGFloat fixPadding = (fixWidth - size.width)/2;
            self.output.rectOfInterest = CGRectMake(cropRect.origin.y/size.height,
                                                        (size.width-(cropRect.size.width+cropRect.origin.x)+fixPadding)/fixWidth,
                                                        cropRect.size.height/size.height,
                                                        cropRect.size.width/fixWidth);
        }
    } else if ([self.preview.videoGravity isEqualToString:AVLayerVideoGravityResizeAspect]) {
        if (p1 > p2) {
            CGFloat fixHeight = size.width * p2;
            CGFloat fixPadding = (fixHeight - size.height)/2;
            self.output.rectOfInterest = CGRectMake((cropRect.origin.y + fixPadding)/fixHeight,
                                                        (size.width-(cropRect.size.width+cropRect.origin.x))/size.width,
                                                        cropRect.size.height/fixHeight,
                                                        cropRect.size.width/size.width);
        } else {
            CGFloat fixWidth = size.height * (1/p2);
            CGFloat fixPadding = (fixWidth - size.width)/2;
            self.output.rectOfInterest = CGRectMake(cropRect.origin.y/size.height,
                                                        (size.width-(cropRect.size.width+cropRect.origin.x)+fixPadding)/fixWidth,
                                                        cropRect.size.height/size.height,
                                                        cropRect.size.width/fixWidth);
        }
    }
}

#pragma mark - 代理方法
/**
 *  如果扫描到了二维码 回调该代理方法
 */
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    
    if(metadataObjects.count > 0 && metadataObjects != nil){
        
        [self.session stopRunning];
        AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects lastObject];

        NSString *result = metadataObject.stringValue;
        NSLog(@"result = %@ ",result);

        if (self.scanBlock) {
            self.scanBlock(metadataObjects, result);
        }
        
    }
    
    
}

/**
 *   蒙版中间一块要空出来
 */

-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
    
    if (layer == self.maskLayer) {
        
        UIGraphicsBeginImageContextWithOptions(self.maskLayer.frame.size, NO, 1.0);
        
        //蒙版新颜色
        CGContextSetFillColorWithColor(ctx, [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:0.8].CGColor);
        
        CGContextFillRect(ctx, self.maskLayer.frame);
        
        //转换坐标
        CGRect scanFrame = [self convertRect:self.frame fromView:self.superview];
        
        //空出中间一块
        CGContextClearRect(ctx, scanFrame);
    }
}

#pragma mark - LAZY LOAD --
-(AVCaptureDevice *)device{
    if (_device == nil) {
        
        _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        
    }
    return _device;
    
}

-(AVCaptureDeviceInput *)input{
    
    if (_input == nil) {
        NSError *err = nil;
        _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:&err];
        
    }
    
    return  _input;
    
}

-(AVCaptureMetadataOutput *)output{
    
    if (_output == nil) {
        
        _output = [[AVCaptureMetadataOutput alloc]init];
        //获取输出需要设置代理，在代理方法中获取
        [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        
    }
    
    return  _output;
}

- (UIView *)centerView {
    
    if (_centerView == nil) {
        _centerView = [[UIView alloc] init];
        _centerView.backgroundColor = UIColor.clearColor;
        
        CGFloat line_w = 4;
        CGFloat line_h = 28;
        for (int i = 0; i < 4; i++) {
            UIView *lineV = [[UIView alloc] init];
            lineV.backgroundColor = UIColorWhite;
            
            UIView *lineH = [[UIView alloc] init];
            lineH.backgroundColor = UIColorWhite;
            
            [_centerView addSubview:lineH];
            [_centerView addSubview:lineV];
            [lineV mas_makeConstraints:^(MASConstraintMaker *make) {
               
                make.height.mas_equalTo(line_w);
                make.width.mas_equalTo(line_h);
                
                if (i < 2) {
                    make.top.equalTo(_centerView.mas_top);
                    if (i == 0) {
                        make.left.equalTo(_centerView);
                    }else {
                        make.right.equalTo(_centerView);
                    }
                }else {
                    make.bottom.equalTo(_centerView.mas_bottom);
                    if (i == 2) {
                        make.left.equalTo(_centerView);
                    }else {
                        make.right.equalTo(_centerView);
                    }
                }
                
            }];
            [lineH mas_makeConstraints:^(MASConstraintMaker *make) {
               
                make.height.mas_equalTo(line_h);
                make.width.mas_equalTo(line_w);
                
                if (i < 2) {
                    make.top.equalTo(_centerView.mas_top);
                    if (i == 0) {
                        make.left.equalTo(_centerView);
                    }else {
                        make.right.equalTo(_centerView);
                    }
                }else {
                    make.bottom.equalTo(_centerView.mas_bottom);
                    if (i == 2) {
                        make.left.equalTo(_centerView);
                    }else {
                        make.right.equalTo(_centerView);
                    }
                }
                
            }];
        }
    }
    
    return _centerView;
}

- (UIView *)lineView {
    
    if (_lineView == nil) {
        _lineView = [[UIView alloc] initWithFrame:CGRectMake(5, 10, 240, 1)];
        _lineView.layer.cornerRadius = 2;
        _lineView.layer.masksToBounds = YES;
        _lineView.backgroundColor = UIColor.qd_tintColor;
    }
    
    return _lineView;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/



@end
